﻿/*----------------------------------------------------------------
 * 
 * 版权所有：Copyright (C) 2013
 * 
 * 文件名：StringHelper.cs
 * 文件功能描述：
 * 
 * 
 * 作 者：zhangq
 * 邮 箱：ifunnyface@outlook.com
 * 日 期：2013-02-27 15:57:33
 * 
 * 
 * 修改标识： Author
 * 修改描述： 相关描述
 * 
 * ---------------------------------------------------------------- */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Common.Extensions
{

    /// <summary>
    /// 
    /// </summary>
    public static class StringHelper
    {
        #region String length formatter

        /// <summary>
        /// 对字符串进行裁剪
        /// </summary>
        /// <param name="maxLength">双字节长度 全角字符长度</param>
        /// <returns></returns>
        public static string Trim(this string self, int maxLength)
        {
            if (self == null)
            {
                return string.Empty;
            }
            return Trim(self, maxLength, "...");
        }

        /**/
        ///   <summary>
        ///   去除HTML标记
        ///   </summary>
        ///   <param   name="htmlString">包括HTML的源码   </param>
        ///   <returns>已经去除后的文字</returns>
        public static string RemoveHTML(this string htmlString)
        {
            if (string.IsNullOrEmpty(htmlString))
            {
                return string.Empty;
            }
            //删除脚本
            htmlString = Regex.Replace(htmlString, @"<script[^>]*?>.*?</script>", "",
              RegexOptions.IgnoreCase);
            //删除HTML
            htmlString = Regex.Replace(htmlString, @"<(.[^>]*)>", "",
              RegexOptions.IgnoreCase);
            htmlString = Regex.Replace(htmlString, @"([\r\n])[\s]+", "",
              RegexOptions.IgnoreCase);
            htmlString = Regex.Replace(htmlString, @"-->", "", RegexOptions.IgnoreCase);
            htmlString = Regex.Replace(htmlString, @"<!--.*", "", RegexOptions.IgnoreCase);
            htmlString = Regex.Replace(htmlString, @"&(quot|#34);", "\"",
              RegexOptions.IgnoreCase);
            htmlString = Regex.Replace(htmlString, @"&(amp|#38);", "&",
              RegexOptions.IgnoreCase);
            htmlString = Regex.Replace(htmlString, @"&(lt|#60);", "<",
              RegexOptions.IgnoreCase);
            htmlString = Regex.Replace(htmlString, @"&(gt|#62);", ">",
              RegexOptions.IgnoreCase);
            htmlString = Regex.Replace(htmlString, @"&(nbsp|#160);", "   ",
              RegexOptions.IgnoreCase);
            htmlString = Regex.Replace(htmlString, @"&(iexcl|#161);", "\xa1",
              RegexOptions.IgnoreCase);
            htmlString = Regex.Replace(htmlString, @"&(cent|#162);", "\xa2",
              RegexOptions.IgnoreCase);
            htmlString = Regex.Replace(htmlString, @"&(pound|#163);", "\xa3",
              RegexOptions.IgnoreCase);
            htmlString = Regex.Replace(htmlString, @"&(copy|#169);", "\xa9",
              RegexOptions.IgnoreCase);
            htmlString = Regex.Replace(htmlString, @"&#(\d+);", "",
              RegexOptions.IgnoreCase);

            htmlString.Replace("<", "");
            htmlString.Replace(">", "");
            htmlString.Replace("\r\n", "");
            //Htmlstring = HttpContext.Current.Server.HtmlEncode(Htmlstring).Trim();

            return htmlString;
        }



        /// <summary>  
        /// 对字符串进行裁剪(区分单字节及双字节字符)  
        /// </summary>  
        /// <param name="rawString">需要裁剪的字符串</param>  
        /// <param name="maxLength">裁剪的长度，按双字节计数</param>  
        /// <param name="appendString">如果进行了裁剪需要附加的字符</param>  
        static string Trim(string rawString, int maxLength, string appendString)
        {
            if (string.IsNullOrEmpty(rawString) || rawString.Length <= maxLength)
            {
                return rawString;
            }
            else
            {
                int rawStringLength = Encoding.UTF8.GetBytes(rawString).Length;
                if (rawStringLength <= maxLength * 2)
                    return rawString;
            }

            int appendStringLength = Encoding.UTF8.GetBytes(appendString).Length;
            StringBuilder checkedStringBuilder = new StringBuilder();
            int appendedLenth = 0;
            for (int i = 0; i < rawString.Length; i++)
            {
                char _char = rawString[i];
                checkedStringBuilder.Append(_char);

                appendedLenth += Encoding.Default.GetBytes(new char[] { _char }).Length;

                if (appendedLenth >= maxLength * 2 - appendStringLength)
                    break;
            }

            return checkedStringBuilder.ToString() + appendString;
        }


        #endregion

        #region 特殊字符


        /// <summary>  
        /// 清除xml中的不合法字符  
        /// </summary>  
        /// <remarks>  
        /// 无效字符：  
        /// 0x00 - 0x08  
        /// 0x0b - 0x0c  
        /// 0x0e - 0x1f  
        /// </remarks>  
        public static string CleanInvalidCharsForXML(string input)
        {
            if (string.IsNullOrEmpty(input))
                return input;
            else
            {
                StringBuilder checkedStringBuilder = new StringBuilder();
                Char[] chars = input.ToCharArray();
                for (int i = 0; i < chars.Length; i++)
                {
                    int charValue = Convert.ToInt32(chars[i]);

                    if ((charValue >= 0x00 && charValue <= 0x08) || (charValue >= 0x0b && charValue <= 0x0c) || (charValue >= 0x0e && charValue <= 0x1f))
                        continue;
                    else
                        checkedStringBuilder.Append(chars[i]);
                }

                return checkedStringBuilder.ToString();

                //string result = checkedStringBuilder.ToString();  
                //result = result.Replace("&#x0;", "");  
                //return Regex.Replace(result, @"[\?-\\ \ \-\\?-\?]", delegate(Match m) { int code = (int)m.Value.ToCharArray()[0]; return (code > 9 ? "&#" + code.ToString() : "&#0" + code.ToString()) + ";"; });  
            }
        }


        /// <summary>  
        ///  判断是否有非法字符 
        /// </summary>  
        /// <param name="strString"></param>  
        /// <returns>返回TRUE表示有非法字符，返回FALSE表示没有非法字符。</returns>  
        public static bool UnSafe(this string strString)
        {
            if (strString != null && strString.Length > 0)
            {

                string tempStr = strString.ToLower();
                foreach (string key in keys)
                {
                    if (tempStr.Contains(key))
                    {
                        return true;
                    }
                }
            }
            return false;
        }


        /// <summary>
        /// SQL关键字、字符
        /// </summary>
        static IList<string> keys = new List<string>()
                {
                    "'",
                    ";",
                    ":",
                    "%",
                    "@",
                    "&",
                    "#",
                    "\"",
                    "net user",
                    "exec",
                    "net localgroup",
                    "select",
                    "asc",
                    "char",
                    "mid",
                    "insert",
                    "order",
                    "exec",
                    "delete",
                    "drop",
                    "truncate",
                    "xp_cmdshell",
                    "<",
                    ">",
                    "update"
                };


        /// <summary>  
        ///  判断安全性
        /// </summary>  
        /// <param name="strString"></param>  
        /// <returns>返回合法字符。</returns>  
        public static string Safe(this string strString)
        {
            if (strString != null && strString.Length > 0)
            {
                string tempStr = strString.ToLower();
                foreach (string key in keys)
                {
                    if (tempStr.Contains(key))
                    {
                        throw new Exception("SQL语句含有非法字符");
                    }
                }
            }
            return strString;
        }
        #endregion
         
    }

}